﻿namespace SharePoint.ImportExport.Core
{
    using System;
    using System.Collections;
    using System.Globalization;
    using System.IO;
    using System.Xml.Serialization;

    /// <summary>
    /// This is the enumeration of list types
    /// </summary>
    /// <remarks>
    /// Valid choices are Library or folder</remarks>
    public enum ListType
    {
        /// <summary>
        /// Default value used only to ensure that the correct value is set
        /// </summary>
        Undefined,

        /// <summary>
        /// Type library
        /// </summary>
        Library,

        /// <summary>
        /// Type folder is only allowed for document libraries
        /// </summary>
        Folder
    }

    /// <summary>
    /// This is the enumeration of site types
    /// </summary>
    public enum SiteType
    {
        /// <summary>
        /// Default value used only to ensure that the correct value is set
        /// </summary>
        Undefined,

        /// <summary>
        /// The resource is a team site
        /// </summary>
        Site,

        /// <summary>
        /// Portal Area (Obsolete)
        /// </summary>
        Area
    }

    /// <summary>
    /// This is the enum that controls the site/list/library creation
    /// </summary>
    public enum Verb
    {
        /// <summary>
        /// The site will be created(fails if it already exists) 
        /// </summary>
        Create,

        /// <summary>
        /// The site will be modified. The settings will be changed and items appended unless they are created/modified on the same date by the same author/editor 
        /// </summary>
        Modify,

        /// <summary>
        /// The site will be deleted
        /// </summary>
        Delete,

        /// <summary>
        /// The site will be emptied
        /// </summary>
        Clear
    }

    /// <summary>
    /// This is the enumeration of the AlertTypes
    /// </summary>
    public enum AlertType
    {
        /// <summary>
        /// Alert of type Add
        /// </summary>
        Add,

        /// <summary>
        /// Alert of type All
        /// </summary>
        All,

        /// <summary>
        /// Alert of type Delete
        /// </summary>
        Delete,

        /// <summary>
        /// Alert of type Discussion
        /// </summary>
        Discussion,

        /// <summary>
        /// Alert of type Modify
        /// </summary>
        Modify
    }

#if(DEBUG)
    /// <summary>
    /// This class is designed to facilitate the creation of the datafiles needed by the SharePoint Importer
    /// A good starting point is <see cref="SharePoint.ImportExport.Core.Import"/>
    /// <example>
    /// <code>
    /// //Create a new instance of the Import class
    /// SharePointExtractor.Import import = new Import();
    /// import.Settings.Locale="1033"; //US english
    /// <para></para>
    /// Root rootContainer= new Root();
    /// rootContainer.Type=SiteType.Site; //WSS site, SiteType.Area=Portal area
    /// rootContainer.Name=""; //Create the sites in the root of the WSS server 
    /// <para></para>
    /// //This class is the actual site that will be created
    /// SharePointExtractor.Site site= new Site();
    /// rootContainer.Containers.Add(site);
    /// import.RootContainers.Add(rootContainer);
    /// <para></para>
    /// site.Name="Test";
    /// site.Owner="DOMAIN\\user";
    /// site.Contact="user@domain.com";
    /// site.Type=SiteType.Site;
    /// site.Template="STS#1"; //Empty WSS Team site
    /// <para></para>
    /// //Add an contributor
    /// User user= new User();
    /// user.Account="DOMAIN\\User2";
    /// user.Role="contributor";
    /// user.Email="user2@domain.com";
    /// user.Name="Joe User";
    /// user.Type="Person";
    /// site.Security.Users.Add(user);
    /// <para></para>
    /// //Create a document library
    /// SharePointExtractor.List list=new List();
    /// list.Name="My Document Library";
    /// list.Type=ListType.Library;
    /// <para></para>
    /// // Use then custom List Template
    /// list.Template="My Library";
    /// // That is based on the documentlibrary template
    /// list.BaseTemplate="DocumentLibrary";
    /// list.WebPart=true;
    /// list.QuickLaunch=true;
    /// list.RelativeitemXML="\\items.xml"; //This is the path to the file with the items
    /// site.Lists.Add(list);
    /// //Create a new list object that will contain the actual items
    /// List list = new List();
    /// ItemType profile = new ItemType();
    /// profile.Name=list.Template;
    /// list.ItemTypes.Add(profile);
    /// try
    ///  {
    ///    list.Serialize("items.xml");
    ///  }
    /// catch(SPExportException ex)
    ///  {
    ///   Console.WriteLine("Exception occurred: "+ex.Message);
    ///  }
    /// 
    /// //Validate the schema prior to saving
    /// if(!import.Validate())
    ///  {
    ///   Console.WriteLine("Validation failed, last error: "+import.LastError)
    ///  }
    /// else
    ///  {
    ///   try
    ///    {
    ///     import.Serialize("struct.xml");
    ///    }
    ///   catch(SPExportException ex)
    ///    {
    ///     Console.WriteLine("Exception occurred: "+ex.Message);
    ///    }
    /// }
    /// </code>
    /// </example>
    /// </summary>
#endif
    /// <summary>
    /// This is the main class for creating the exported data. 
    /// </summary>
    /// <remarks>There has to be exactly one instance of this class for each struct.xml file. <seealso cref="SharePoint.ImportExport.Core.Root"/><seealso cref="SharePoint.ImportExport.Core.List"/><seealso cref="SharePoint.ImportExport.Core.Site"/></remarks>
    /// <example>
    /// <code>
    /// //Create a new instance of the Import class
    /// SharePoint.ImportExport.Core.Import import = new Import();
    /// import.Settings.Locale="1033"; //US english
    /// <para></para>
    /// Root rootContainer= new Root();
    /// rootContainer.Type=SiteType.Site; //WSS site, SiteType.Area=Portal area
    /// rootContainer.Name=""; //Create the sites in the root of the WSS server 
    /// <para></para>
    /// //This class is the actual site that will be created
    /// SharePoint.ImportExport.Core.Site site= new Site();
    /// rootContainer.Sites.Add(site);
    /// import.RootContainers.Add(rootContainer);
    /// <para></para>
    /// site.Name="Test";
    /// site.Owner="DOMAIN\\user";
    /// site.Contact="user@domain.com";
    /// site.Type=SiteType.Site;
    /// site.Template="STS#1"; //Empty WSS Team site
    /// <para></para>
    /// //Add an contributor
    /// User user= new User();
    /// user.Account="DOMAIN\\User2";
    /// user.Role="contributor";
    /// user.Email="user2@domain.com";
    /// user.Name="Joe User";
    /// user.Type="Person";
    /// site.UserInformation.Users.Add(user);
    /// <para></para>
    /// //Create a document library
    /// SharePoint.ImportExport.Core.List list=new List();
    /// list.Name="My Document Library";
    /// list.Type=ListType.Library;
    /// <para></para>
    /// // Use then custom List Template
    /// list.Template="My Library";
    /// // That is based on the documentlibrary template
    /// list.BaseTemplate="DocumentLibrary";
    /// list.WebPart=true;
    /// list.QuickLaunch=true;
    /// list.RelativeitemXML="\\items.xml"; //This is the path to the file with the items
    /// site.Lists.Add(list);
    /// //Create a new list object that will contain the actual items
    /// List list = new List();
    /// ItemType profile = new ItemType();
    /// profile.Name=list.Template;
    /// list.ItemTypes.Add(profile);
    /// try
    /// {
    ///   list.Serialize("items.xml");
    /// }
    /// catch(SPExportException ex)
    ///  {
    ///   Console.WriteLine("Exception occurred: "+ex.Message);
    ///  }
    /// <para></para>
    /// //Validate the schema prior to saving
    /// if(!import.Validate())
    ///  Console.WriteLine("Validation failed, last error: "+import.LastError);
    /// else
    ///  {
    ///   try
    ///    {
    ///      import.Serialize("struct.xml");
    ///    }
    ///   catch(SPExportException ex)
    ///    {
    ///     Console.WriteLine("Exception occurred: "+ex.Message);
    ///    }
    ///  }
    /// <para></para>
    /// </code>
    /// </example>
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public class Import
    {
        /// <summary>
        /// This is the collection of start addresses
        /// </summary>
        private RootsCollection rootContainers;

        /// <summary>
        /// This is the settings node
        /// </summary>
        private Settings settings;

        /// <summary>
        /// This is the last error from the validation
        /// </summary>
        private string lastError = String.Empty;

        /// <summary>
        /// Initializes a new instance of the Import class.
        /// </summary>
        public Import()
        {
            this.rootContainers = new RootsCollection();
            this.settings = new Settings();
        }

        /// <summary>
        /// Initializes a new instance of the Import class.
        /// </summary>
        /// ´<param name="lcid">This is the locale of the data</param>
        public Import(string lcid)
        {
            this.rootContainers = new RootsCollection();
            this.settings = new Settings();
            this.settings.Locale = lcid;
        }

        /// <summary>
        /// Initializes a new instance of the Import class.
        /// </summary>
        /// <param name="lcid">This is the locale of the data</param>
        /// <param name="rootContainerType">This is the site type use: Type</param>
        /// <param name="rootContainerName">This is the managed path</param>
        public Import(string lcid, SiteType rootContainerType, string rootContainerName)
        {
            this.rootContainers = new RootsCollection();
            this.settings = new Settings();
            this.settings.Locale = lcid;
            Root rootContainer = new Root();
            rootContainer.DataType = rootContainerType;
            rootContainer.Name = rootContainerName;
            this.RootContainers.Add(rootContainer);
        }

        /// <summary>
        /// Gets the  last error from the validation
        /// </summary>
        public string LastError
        {
            get
            {
                return this.lastError;
            }
        }

        /// <summary>
        /// Gets or sets the Settings info
        /// </summary>
        /// <remarks>This is used to specify the locale information for the exported data. the importer uses this information in order to parse the dates etc in the right format</remarks>
        [System.Xml.Serialization.XmlElementAttribute("settings", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public Settings Settings
        {
            get
            {
                return this.settings;
            }

            set
            {
                this.settings = value;
            }
        }

        /// <summary>
        /// Gets the array of rootcontainer nodes. The rootcontainer defines the starting point of the import
        /// </summary>
        /// <remarks>Usually the struct.xml file contains just one rootcontainer node</remarks>
        [System.Xml.Serialization.XmlElementAttribute("rootcontainer", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public RootsCollection RootContainers
        {
            get
            {
                return this.rootContainers;
            }
        }

        /// <summary>
        /// This is the serialization function for the import class
        /// </summary>
        /// <param name="fileName">this is the name of the XML file that will be generated</param>
        /// <returns>True if validation succeeded</returns>
        /// <remarks>The method will throw as SPExportException if the data is invalid</remarks>
        public bool Serialize(string fileName)
        {
            string dirName = fileName;
            int pos = dirName.LastIndexOf("\\", StringComparison.InvariantCulture);

            if (pos > 0)
            {
                dirName = dirName.Substring(0, pos);
            }

            if (pos != -1)
            {
                if (!Directory.Exists(dirName))
                {
                    Directory.CreateDirectory(dirName);
                }
            }

            if (!this.Validate())
            {
                throw new SPExportException(this.LastError);
            }

            using (StreamWriter exportFile = new StreamWriter(fileName, false))
            {
                try
                {
                    XmlSerializer mySerializer = new XmlSerializer(typeof(Import));
                    mySerializer.Serialize(exportFile, this);
                }
                catch (IOException serializationException)
                {
                    Console.WriteLine("Exception error: " + serializationException.Message);
                    SPExportException ex = new SPExportException(serializationException.Message);
                    throw ex;
                }
                finally
                {
                    exportFile.Flush();
                    exportFile.Close();
                }
            }

            return true;
        }

        /// <summary>
        /// This function validates the class
        /// </summary>
        /// <returns>True if validation succeeded</returns>
        public bool Validate()
        {
            bool returnValue = true;
            if (Settings == null)
            {
                this.lastError = "The settings must be defined";
                return false;
            }
            else
            {
                if (String.IsNullOrEmpty(Settings.Locale))
                {
                    Settings.Locale = System.Threading.Thread.CurrentThread.CurrentUICulture.LCID.ToString(CultureInfo.InvariantCulture);
                }
            }

            if (this.RootContainers == null)
            {
                this.lastError = "At least one rootcontainer must be defined";
                return false;
            }
            else
            {
                ////Start validation 
                foreach (Root rootContainer in this.RootContainers)
                {
                    if (rootContainer.DataType == SiteType.Undefined)
                    {
                        this.lastError = "The rootcontainer: " + rootContainer.Name + " must either be of type \"site\" or \"area\"";
                        return false;
                    }

                    if (rootContainer.DataType == SiteType.Site || rootContainer.DataType == SiteType.Area)
                    {
                        if (rootContainer.Sites == null)
                        {
                            this.lastError = "At least one site must be defined in rootcontainer: " + rootContainer.Name;
                            return false;
                        }
                        else
                        {
                            foreach (Site site in rootContainer.Sites)
                            {
                                try
                                {
                                    this.ValidateSite(site);
                                }
                                catch (SPExportException ex)
                                {
                                    this.lastError = ex.Message;
                                    returnValue = false;
                                }
                            }
                        }
                    }
                    else
                    {
                        this.lastError = "The rootcontainer: " + rootContainer.Name + " must either be of type \"site\" or \"area\"";
                        returnValue = false;
                    }
                }
            }

            return returnValue;
        }

        /// <summary>
        /// This validates that all the data is correctly entered
        /// </summary>
        /// <param name="list">This is the list to be validated</param>
        private void ValidateList(List list)
        {
            if (list == null)
            {
                return;
            }

            if (list.DataType == ListType.Undefined)
            {
                throw new SPExportException("A List must have its type defined");
            }

            if (list.Name == null)
            {
                throw new SPExportException("A List must have a name defined");
            }

            if (ListType.Library != list.DataType && ListType.Folder != list.DataType)
            {
                throw new SPExportException("A data site must either be of type  \"Library\" or \"Folder\"");
            }

            if (list.Template == null && list.BaseTemplate == null)
            {
                if (list.DataType != ListType.Folder)
                {
                    throw new SPExportException("A List must have either a template or a base template defined");
                }
            }

            if (list.DataType == ListType.Folder)
            {
                if (list.Folders != null)
                {
                    foreach (List folder in list.Folders)
                    {
                        try
                        {
                            this.ValidateList(folder);
                        }
                        catch (SPExportException exception)
                        {
                            throw exception;
                        }
                    }
                }
            }
            else
            {
                if (list.Folders != null)
                {
                    foreach (List folder in list.Folders)
                    {
                        if (folder.DataType != ListType.Folder)
                        {
                            throw new SPExportException("Child Lists must be of type Folder");
                        }
                        else
                        {
                            try
                            {
                                this.ValidateList(folder);
                            }
                            catch (SPExportException ex)
                            {
                                throw;
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// This validates that all the data is entered correctly
        /// </summary>
        /// <param name="site">This is the site to be validated</param>
        private void ValidateSite(Site site)
        {
            if (String.IsNullOrEmpty(site.Name))
            {
                throw new SPExportException("A Site must have a name defined");
            }

            if (String.IsNullOrEmpty(site.Owner))
            {
                throw new SPExportException("A Site must have an owner defined");
            }

            if (site.DataType == SiteType.Undefined)
            {
                throw new SPExportException("The site: " + site.Name + " must either be of type \"site\" or \"area\"");
            }

            if (site.DataType == SiteType.Site || site.DataType == SiteType.Area)
            {
                if (site.Lists != null)
                {
                    foreach (List list in site.Lists)
                    {
                        if (list != null)
                        {
                            try
                            {
                                this.ValidateList(list);
                            }
                            catch (SPExportException ex)
                            {
                                throw new SPExportException("list validation in site " + site.Name + " failed. Error: " + ex.Message);
                            }
                        }
                    }
                }

                if (site.SubSites != null)
                {
                    foreach (Site subSite in site.SubSites)
                    {
                        if (subSite != null)
                        {
                            try
                            {
                                this.ValidateSite(subSite);
                            }
                            catch (SPExportException ex)
                            {
                                throw new SPExportException("Site validation in site " + site.Name + "failed. Error: " + ex.Message);
                            }
                        }
                    }
                }

                if (site.UserInfo != null)
                {
                    foreach (User user in site.UserInfo.Users)
                    {
                        if (user.Account == null)
                        {
                            throw new SPExportException("The user defined in site " + site.Name + " must have an account defined");
                        }

                        if (user.Role == null)
                        {
                            throw new SPExportException("The user defined in site " + site.Name + " must have a role defined");
                        }
                    }
                }
                if (site.DesignElements!= null)
                {
                    foreach (Page page in site.DesignElements.Pages)
                    {
                        if (String.IsNullOrEmpty(page.URL))
                        {
                            throw new SPExportException("The page defined in site " + site.Name + " must have an url defined");
                        }
                    }

                    foreach (Resource  resource in site.DesignElements.Resources)
                    {
                        if (String.IsNullOrEmpty(resource.URL))
                        {
                            throw new SPExportException("The resource defined in site " + site.Name + " must have an url defined");
                        }
                    }

                }

            }
            else
            {
                throw new SPExportException("The site: " + site.Name + " must either be of type \"site\" or \"area\"");
            }
        }
    }

    /// <summary>
    /// This is the settings class
    /// </summary>
    public class Settings
    {
        /// <summary>
        /// This defines the locale that the data was extacted from
        /// </summary>
        private string locale;

        /// <summary>
        /// Gets or sets the locale that the data was extacted from
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("locale", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Locale
        {
            get
            {
                return this.locale;
            }

            set
            {
                this.locale = value;
            }
        }
    }

    /// <summary>
    /// This is the class implementing the Alerts collection
    /// </summary>
    public class AlertsCollection : ICollection
    {
        /// <summary>
        /// This is the internal list of alerts
        /// </summary>
        private ArrayList alerts;
        
        /// <summary>
        /// Initializes a new instance of the AlertsCollection class.
        /// </summary>
        /// <remarks>Instantiates the alerts member</remarks>
        public AlertsCollection()
        {
            this.alerts = new ArrayList();
        }
        
        #region ICollection Members

        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.alerts.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.alerts.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.alerts.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">This is the index of the item</param>
        public Alert this[int index]
        {
            get
            {
                return (Alert)this.alerts[index];
            }
        }

        /// <summary>
        /// Copies the entire Alert array to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Alert[] a, int index)
        {
            this.alerts.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.alerts.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The enumerator</returns>
        public IEnumerator GetEnumerator()
        {
            return this.alerts.GetEnumerator();
        }

        #endregion

        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newAlert">New Alert to be added to the list</param>
        public void Add(Alert newAlert)
        {
            this.alerts.Add(newAlert);
        }
    }

    /// <summary>
    /// This is the class that encapsulates a WSS alert
    /// </summary>
    /// <example>
    /// <code>
    /// //Create a new alert
    /// Alert alert= new Alert();
    /// alert.Frequency="Daily";
    /// alert.User="DOMAIN\\user";
    /// alert.Type="Modify";
    /// list.Alerts.Alert.Add(alert);
    /// </code>
    /// </example>
    /// <remarks>
    /// Valid choices for Alert.Type are
    /// <list type="bullet">
    /// <item>Add</item>
    /// <item>All</item>
    /// <item>Delete</item>
    /// <item>Discussion</item>
    /// <item>Modify</item>
    /// </list>
    /// </remarks>
    public class Alert
    {
        /// <summary>
        /// This is the user that will receive the alert, format either DOMAIN\user or user@domain.com
        /// </summary>
        private string user;

        /// <summary>
        /// This is the frequency for the alert
        /// </summary>
        /// <remarks>
        /// Valid types are
        /// <list type="bullet">
        /// <item>Daily</item>
        /// <item>Immediate</item>
        /// <item>Weekly</item>
        /// </list>
        /// </remarks>
        private string frequency;

        /// <summary>
        /// This is the type of the alert
        /// </summary>
        /// <remarks>
        /// Valid choices are
        /// <list type="bullet">
        /// <item>Add</item>
        /// <item>All</item>
        /// <item>Delete</item>
        /// <item>Discussion</item>
        /// <item>Modify</item>
        /// </list>
        /// </remarks>
        private AlertType type;

        /// <summary>
        /// Gets or sets the user that the alert belongs to
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("user", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string User
        {
            get
            {
                return this.user;
            }

            set
            {
                this.user = value;
            }
        }

        /// <summary>
        /// Gets or sets the type of the alert
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("type", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public AlertType DataType
        {
            get
            {
                return this.type;
            }

            set
            {
                this.type = value;
            }
        }

        /// <summary>
        /// Gets or sets the frequency of the alert
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("frequency", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Frequency
        {
            get
            {
                return this.frequency;
            }

            set
            {
                this.frequency = value;
            }
        }
    }

    /// <summary>
    /// This is a list of the alerts specified for the list or listitem
    /// </summary>
    /// <remarks>
    /// This class is used to create the WSS alerts</remarks>
    /// <example>
    /// <code>
    /// //Create a new alert
    /// Alert alert= new Alert();
    /// alert.Frequency="Daily";
    /// alert.User="DOMAIN\\user";
    /// alert.Type="Modify";
    /// list.Alerts.Alert.Add(alert);
    /// </code>
    /// </example>
    public class Alerts
    {
        /// <summary>
        /// List of alerts
        /// </summary>
        private AlertsCollection alert;

        /// <summary>
        /// Initializes a new instance of the Alerts class
        /// </summary>
        /// <remarks>Instantiates the Alert member</remarks>
        public Alerts()
        {
            this.alert = new AlertsCollection();
        }

        /// <summary>
        /// Gets the list of alerts
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("alert", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public AlertsCollection Alert
        {
            get
            {
                return this.alert;
            }
        }
    }

    /// <summary>
    /// This is the class implementing the ListsCollection collection
    /// </summary>
    public class ListsCollection : ICollection
    {
        /// <summary>
        /// This is an internal list of datacontainers, ie lists
        /// </summary>
        private ArrayList lists;

        /// <summary>
        /// Initializes a new instance of the ListsCollection class
        /// </summary>
        /// <remarks>Instantiates the dataContainers member</remarks>
        public ListsCollection()
        {
            this.lists = new ArrayList();
        }
        
        #region ICollection Members
        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.lists.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.lists.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.lists.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">This is the index of the item</param>
        public List this[int index]
        {
            get
            {
                return (List)this.lists[index];
            }
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(List[] a, int index)
        {
            this.lists.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.lists.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The enumerator</returns>
        public IEnumerator GetEnumerator()
        {
            return this.lists.GetEnumerator();
        }

        #endregion
        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newList">New List to be added to the list</param>
        public void Add(List newList)
        {
            this.lists.Add(newList);
        }

        /// <summary>
        /// This method removes a named item from the collection
        /// </summary>
        /// <param name="name">This is the name of the node to be removed</param>
        /// <returns>True if item was removed</returns>
        public bool Remove(string name)
        {
            int indexToRemove = -1;
            for (int i = 0; i < this.lists.Count; i++)
            {
                List dc = (List)this.lists[i];
                if (0 == dc.Name.CompareTo(name))
                {
                    indexToRemove = i;
                    break;
                }
            }

            if (indexToRemove >= 0)
            {
                this.lists.RemoveAt(indexToRemove);
            }

            return indexToRemove >= 0;
        }
    }

    /// <summary>
    /// This is the class that encapsulates the list or library
    /// </summary>
    /// <remarks><seealso cref="SharePoint.ImportExport.Core.ItemType"/></remarks>
    /// <example>
    /// <code>
    /// //Create a document library
    /// SharePoint.ImportExport.Core.List list=new List();
    /// list.Name="My Document Library";
    /// list.Type=ListType.Library;
    /// list.Template="My Document Library";// Use then custom List Template
    /// list.BaseTemplate="DocumentLibrary";
    /// list.WebPart=true;
    /// list.QuickLaunch=true;    
    /// list.RelativeitemXML="\\items.xml"; //This is the path to the file with the items
    /// site.Lists.Add(list);
    /// //Create a new list object that will contain the actual items
    /// List list = new List();
    /// ItemType profile = new ItemType();
    /// profile.Name=list.Template;
    /// list.ItemTypes.Add(profile);
    /// try
    ///  {
    ///   list.Serialize("items.xml");
    ///  }
    /// catch(SPExportException ex)
    ///  {
    ///   Console.WriteLine("Exception occurred: "+ex.Message);
    ///  }
    /// <para></para>
    /// ListOfItems linksList = new ListOfItems();
    /// linksList.Template = "Links"; //Use standard links list
    /// linksList.Name = "Created Subsites";
    /// linksList.WebPart = true;
    /// linksList.InheritPermissions = true;
    /// linksList.RelativeitemXML = relativePath+"ListItems.xml";
    /// linksList.Type = ListType.Library;
    /// site.Lists.Add(linksList);
    /// </code>
    /// </example>
    public class List
    {
        /// <summary>
        /// This is the type of the list/library.
        /// </summary>
        /// <remarks>In most cases this is "Library" but for sub folders in a document library it is "Folder"<seealso cref="SharePoint.ImportExport.Core.List"></seealso> and <seealso cref="SharePoint.ImportExport.Core.Site"/>"/></remarks>
        private ListType type = ListType.Undefined;

        /// <summary>
        /// This is the name of the list/library
        /// </summary>
        private string name;

        /// <summary>
        /// This is the template the list/library is based on
        /// </summary>
        private string template;

        /// <summary>
        /// This is the base template that the custom list is based on (optional)
        /// </summary>
        private string baseTemplate;

        /// <summary>
        /// This is the relative path to the items.xml file
        /// </summary>
        private string relativeitemXML;

        /// <summary>
        /// This is the relative path to the items.xml file
        /// </summary>
        private bool quickLaunch;

        /// <summary>
        /// Boolean flag indicating whether the list/library will be added to the Quick Launch bar
        /// </summary>
        private bool webPart;

        /// <summary>
        /// Boolean flag indicating whether permissions are inherited
        /// </summary>
        private bool inheritPermissions = true;

        /// <summary>
        /// This is the internal collection of folders
        /// </summary>
        private ListsCollection folders;

        /// <summary>
        /// This is the internal collection of alerts
        /// </summary>
        private AlertsCollection alerts;

        /// <summary>
        /// This is the security node
        /// </summary>
        private UserInfo userInfo;

        /// <summary>
        /// This is the internal collection of views
        /// </summary>
        private ViewsCollection views = null;

        /// <summary>
        /// This will contain all the extra properties not included in the xml schema
        /// </summary>
        private string propertyBag;

        /// <summary>
        /// Location of the default template for the library
        /// </summary>
        private string documenttemplateurl = String.Empty;

        /// <summary>
        /// This indicates whether the list/library is hidden or not
        /// </summary>
        private bool hidden = false;

        /// <summary>
        /// This is the enumeration controlling what operations will be doce
        /// </summary>
        private Verb operation = Verb.Create;

        /// <summary>
        /// This is a list of the metadata fields
        /// </summary>
        private FieldsCollection fields;

        /// <summary>
        /// Initializes a new instance of the List class
        /// </summary>
        /// <remarks>Instantiates the ChildDataContainer member</remarks>
        public List()
        {
            this.folders = new ListsCollection();
            this.userInfo = new UserInfo();
            this.alerts = new AlertsCollection();
            this.DataType = ListType.Library;
            this.views = new ViewsCollection();
            this.fields = new FieldsCollection();
        }

        /// <summary>
        /// Gets or sets the type of the class (Library/Folder)
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("type", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public ListType DataType
        {
            get
            {
                return this.type;
            }

            set
            {
                this.type = value;
            }
        }

        /// <summary>
        /// Gets or sets the name of the list
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("name", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                this.name = Miscallaneous.FixName(value);
            }
        }

        /// <summary>
        /// Gets or sets the template the list/library is based on
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("template", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Template
        {
            get
            {
                return this.template;
            }

            set
            {
                this.template = value;
            }
        }

        /// <summary>
        /// Gets or sets the base template the custom list/library template is based on
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("basetemplate", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string BaseTemplate
        {
            get
            {
                return this.baseTemplate;
            }

            set
            {
                this.baseTemplate = value;
            }
        }

        /// <summary>
        /// Gets or sets the relative path to the xml file containing the data
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("relativeitemXML", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string RelativeitemXML
        {
            get
            {
                return this.relativeitemXML;
            }

            set
            {
                this.relativeitemXML = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the list will be shown in the Quick Launch bar or not
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("quicklaunch", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool QuickLaunch
        {
            get
            {
                return this.quickLaunch;
            }

            set
            {
                this.quickLaunch = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether a list webpart will be added to the default page
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("webpart", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool WebPart
        {
            get
            {
                return this.webPart;
            }

            set
            {
                this.webPart = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the permissions are inherited from the parent
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("inheritPermissions", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool InheritPermissions
        {
            get
            {
                return this.inheritPermissions;
            }

            set
            {
                this.inheritPermissions = value;
            }
        }

        /// <summary>
        /// Gets the array of child datacontainers (subfolders)
        /// </summary>
        /// <remarks>Valid only for document libraries</remarks>
        [System.Xml.Serialization.XmlElementAttribute("datacontainer", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public ListsCollection Folders
        {
            get
            {
                return this.folders;
            }
        }

        /// <summary>
        /// Gets the list of list alerts created for this list/library
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("alerts", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public AlertsCollection Alerts
        {
            get
            {
                return this.alerts;
            }
        }

        /// <summary>
        /// Gets the security information that will be applied to the library
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("security", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public UserInfo UserInfo
        {
            get
            {
                return this.userInfo;
            }
        }

        /// <summary>
        /// Gets the list of the views 
        /// </summary>
        [System.Xml.Serialization.XmlArrayAttribute("views", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        [System.Xml.Serialization.XmlArrayItemAttribute("view", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
        public ViewsCollection Views
        {
            get
            {
                return this.views;
            }
        }

        /// <summary>
        /// Gets or sets the location of the default template for the library
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("documenttemplateurl", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string DocumentTemplateUrl
        {
            get
            {
                return this.documenttemplateurl;
            }

            set
            {
                this.documenttemplateurl = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether a list/library is hidden or not
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("hidden", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool Hidden
        {
            get
            {
                return this.hidden;
            }

            set
            {
                this.hidden = value;
            }
        }

        /// <summary>
        /// Gets or sets the enum controlling the site creation
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("operation", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public Verb Operation
        {
            get
            {
                return this.operation;
            }

            set
            {
                this.operation = value;
            }
        }

        /// <summary>
        /// Gets or sets the value that will contain all the extra properties not included in the xml schema
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("propertyBag", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string PropertyBag
        {
            get
            {
                return this.propertyBag;
            }

            set
            {
                this.propertyBag = value;
            }
        }

        /// <summary>
        /// Gets a list of  metadata fields
        /// </summary>
        [System.Xml.Serialization.XmlArrayAttribute("fields", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        [System.Xml.Serialization.XmlArrayItemAttribute("field", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
        public FieldsCollection Fields
        {
            get
            {
                return this.fields;
            }
        }

    }

    /// <summary>
    /// This is the class implementing the Users collection
    /// </summary>
    public class UsersCollection : ICollection
    {
        /// <summary>
        /// Internal list of users
        /// </summary>
        private ArrayList users;

        /// <summary>
        /// Initializes a new instance of the UsersCollection class
        /// </summary>
        /// <remarks>Instantiates the users member</remarks>
        public UsersCollection()
        {
            this.users = new ArrayList();
        }
        
        #region ICollection Members

        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.users.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.users.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.users.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">This is the index of the item</param>
        public User this[int index]
        {
            get
            {
                return (User)this.users[index];
            }
        }

        /// <summary>
        /// Copies the entire User Array to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(User[] a, int index)
        {
            this.users.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.users.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The enumerator</returns>
        public IEnumerator GetEnumerator()
        {
            return this.users.GetEnumerator();
        }

        #endregion
        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newUser">New User to be added to the list</param>
        public void Add(User newUser)
        {
            this.users.Add(newUser);
        }

        /// <summary>
        /// This method removes a named item from the collection
        /// </summary>
        /// <param name="name">This is the name of the User to be removed</param>
        /// <returns>True if item was removed</returns>
        public bool Remove(string name)
        {
            int indexToRemove = -1;
            for (int i = 0; i < this.users.Count; i++)
            {
                User u = (User)this.users[i];
                if (0 == u.Name.CompareTo(name))
                {
                    indexToRemove = i;
                    break;
                }
            }
            
            if (indexToRemove >= 0)
            {
                this.users.RemoveAt(indexToRemove);
            }

            return indexToRemove >= 0;
        }
    }

    /// <summary>
    /// This class represents the user/group that will be added to the SharePoint site.
    /// </summary>
    public class User
    {
        /// <summary>
        /// This is the role the user is a member of
        /// </summary>
        private string role;

        /// <summary>
        /// This is the domain account of the user
        /// </summary>
        private string account;

        /// <summary>
        /// This is the email address of the user
        /// </summary>
        private string email;

        /// <summary>
        /// This is the name of the user
        /// </summary>
        private string name;

        /// <summary>
        /// This is the type of the user (Person/Group)
        /// </summary>
        private string type;

        /// <summary>
        /// These are the WSS permissions
        /// </summary>
        private string permissions;

        /// <summary>
        /// This is the XML representation of the user
        /// </summary>
        private string xml;

        /// <summary>
        /// Gets or sets the SharePoint roles of the user
        /// </summary>
        /// <remarks>
        /// Usual values is one of these Reader, Contributor, Web Designer, Administrator
        /// </remarks>
        [System.Xml.Serialization.XmlElementAttribute("role", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Role
        {
            get
            {
                return this.role;
            }

            set
            {
                this.role = value;
            }
        }

        /// <summary>
        /// Gets or sets the domain account name of the user
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("account", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Account
        {
            get
            {
                return this.account;
            }

            set
            {
                this.account = value;
            }
        }

        /// <summary>
        /// Gets or sets the email address of the user
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("email", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Email
        {
            get
            {
                return this.email;
            }
         
            set
            {
                this.email = value;
            }
        }

        /// <summary>
        /// Gets or sets the display name of the user
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("name", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                this.name = value;
            }
        }

        /// <summary>
        /// Gets or sets the type of the class (Person/Group)
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("type", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string UserType
        {
            get
            {
                return this.type;
            }

            set
            {
                this.type = value;
            }
        }
        
        /// <summary>
        /// Gets or sets the permissions
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("permissions", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Permissions
        {
            get
            {
                return this.permissions;
            }

            set
            {
                this.permissions = value;
            }
        }

        /// <summary>
        /// Gets or sets the XML representation of the user
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("xml", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Xml
        {
            get
            {
                return this.xml;
            }

            set
            {
                this.xml = value;
            }
        }
    }

    /// <summary>
    /// This is the class implementing the Roles collection
    /// </summary>
    public class RolesCollection : ICollection
    {
        /// <summary>
        /// This is the internal collection of roles
        /// </summary>
        private ArrayList roles;
        
        /// <summary>
        /// Initializes a new instance of the RolesCollection class
        /// </summary>
        /// <remarks>Instantiates the roles member</remarks>
        public RolesCollection()
        {
            this.roles = new ArrayList();
        }
        
        #region ICollection Members

        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.roles.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.roles.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.roles.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">This is the index of the item</param>
        public Role this[int index]
        {
            get
            {
                return (Role)this.roles[index];
            }
        }

        /// <summary>
        /// Copies the entire Role Array to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Role[] a, int index)
        {
            this.roles.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.roles.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The enumerator</returns>
        public IEnumerator GetEnumerator()
        {
            return this.roles.GetEnumerator();
        }

        #endregion
        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newRole">New Role to be added to the list</param>
        public void Add(Role newRole)
        {
            this.roles.Add(newRole);
        }
    }

    /// <summary>
    /// Class encapsulating an Role
    /// </summary>
    public class Role
    {
        /// <summary>
        /// This is the role of the role
        /// </summary>
        private string roleName;

        /// <summary>
        /// This is the Permission of the role
        /// </summary>
        private string permissions;

        /// <summary>
        /// This is the XML representation of the role
        /// </summary>
        private string xml;

        /// <summary>
        /// Gets or sets the Role name
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("name", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string RoleName
        {
            get
            {
                return this.roleName;
            }

            set
            {
                this.roleName = value;
            }
        }

        /// <summary>
        /// Gets or sets the Permission of the role
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("permissions", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Permissions
        {
            get
            {
                return this.permissions;
            }

            set
            {
                this.permissions = value;
            }
        }

        /// <summary>
        /// Gets or sets the XML representation of the role
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("xml", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Xml
        {
            get
            {
                return this.xml;
            }

            set
            {
                this.xml = value;
            }
        }
    }

    /// <summary>
    /// This is the class implementing the SitesCollection collection
    /// </summary>
    public class SitesCollection : ICollection
    {
        /// <summary>
        /// This is an internal list of containers, ie sites
        /// </summary>
        private ArrayList sites;

        /// <summary>
        /// Initializes a new instance of the SitesCollection class
        /// </summary>
        /// <remarks>Instantiates the containers member</remarks>
        public SitesCollection()
        {
            this.sites = new ArrayList();
        }
        
        #region ICollection Members

        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.sites.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.sites.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.sites.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">This is the index of the item</param>
        public Site this[int index]
        {
            get
            {
                return (Site)this.sites[index];
            }
        }

        /// <summary>
        /// Copies the entire Site Array to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Site[] a, int index)
        {
            this.sites.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.sites.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The enumerator</returns>
        public IEnumerator GetEnumerator()
        {
            return this.sites.GetEnumerator();
        }

        #endregion
        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newSite">New Site to be added to the list</param>
        public void Add(Site newSite)
        {
            this.sites.Add(newSite);
        }

        /// <summary>
        /// This method removes a named item from the collection
        /// </summary>
        /// <param name="name">This is the name of the site to be removed</param>
        /// <returns>True if item was removed</returns>
        public bool Remove(string name)
        {
            int indexToRemove = -1;
            for (int i = 0; i < this.sites.Count; i++)
            {
                Site c = (Site)this.sites[i];
                if (0 == c.Name.CompareTo(name))
                {
                    indexToRemove = i;
                    break;
                }
            }

            if (indexToRemove >= 0)
            {
                this.sites.RemoveAt(indexToRemove);
            }

            return indexToRemove >= 0;
        }
    }

    /// <summary>
    /// This class representates the actual site/Area that will be created by the Importer
    /// </summary>
    /// <remarks><seealso cref="SharePoint.ImportExport.Core.UserInfo"/><seealso cref="SharePoint.ImportExport.Core.List"/>
    /// </remarks>
    /// <example>
    /// <code>
    /// //This class is the actual site that will be created
    /// SharePoint.ImportExport.Core.Site site= new Site();
    /// rootContainer.Sites.Add(site);
    /// site.Name="Test";
    /// site.Owner="DOMAIN\\user";
    /// site.Contact="user@domain.com";
    /// site.Type="site";
    /// site.Template="STS#1";
    /// <para></para>
    /// //Add an contributor
    /// User user= new User();
    /// user.Account="DOMAIN\\User2";
    /// user.Role="contributor";
    /// user.Email="user2@domain.com";
    /// user.Name="Joe User";
    /// user.Type="Person";
    /// site.UserInfo.Users.Add(user);
    /// </code></example>
    public class Site
    {
        /// <summary>
        /// This is the template that is used for the site/area
        /// </summary>
        /// <remarks>The template name corresponds to the directory name on the Web Front End Server. 
        /// STS#1 for an empty WSS site</remarks>
        private string template = String.Empty;

        /// <summary>
        /// This is the owner information for the site/area
        /// </summary>
        private string owner;

        /// <summary>
        /// This is the site type that gets created ("site"=WSS,"area"=SPS) 
        /// </summary>
        private SiteType type = SiteType.Undefined;

        /// <summary>
        /// This is the name of the site/area that gets created
        /// </summary>
        private string name;

        /// <summary>
        /// This is the description for the site/area
        /// </summary>
        private string description;

        /// <summary>
        /// This is the contact information for the site/area
        /// </summary>
        private string contact;

        /// <summary>
        /// This is a list of all the lists/libraries that will be created in the site/area
        /// </summary>
        private ListsCollection lists;

        /// <summary>
        /// This is the collection of sub sites
        /// </summary>
        private SitesCollection subSites;

        /// <summary>
        /// This is the TimeZone Id
        /// </summary>
        private int timezoneID = 0;

        /// <summary>
        /// This will contain all the extra properties not included in the xml schema
        /// </summary>
        private string propertyBag;

        /// <summary>
        /// This is the enum controlling the creation/modification
        /// </summary>
        private Verb operation = Verb.Create;

        /// <summary>
        /// This is the site specific locale
        /// </summary>
        private int sitelcid = System.Threading.Thread.CurrentThread.CurrentUICulture.LCID;

        /// <summary>
        /// This is the locale of the data
        /// </summary>
        private int lcid = System.Threading.Thread.CurrentThread.CurrentUICulture.LCID;

        /// <summary>
        /// This stores the Url for the site/area
        /// </summary>
        private string url;

        /// <summary>
        /// This wraps the design info for the site/area
        /// </summary>
        private DesignElement design;

        /// <summary>
        /// This stores the configuration for the site/area
        /// </summary>
        private string configuration;

        /// <summary>
        /// This stores the template for the site/area
        /// </summary>
        private string webtemplate;

        /// <summary>
        /// Boolean flag indicationg whether the site will be added to the site directory on the portal
        /// </summary>
        private bool showInSiteDirectory;

        /// <summary>
        /// Boolean flag indication whether the permissions are inherited from the parent
        /// </summary>
        private bool inheritPermissions = true;

        /// <summary>
        /// This is the security node
        /// </summary>
        private UserInfo security;

        /// <summary>
        /// Initializes a new instance of the Site class
        /// </summary>
        public Site()
        {
            this.subSites = new SitesCollection();
            this.lists = new ListsCollection();
            this.security = new UserInfo();
            this.design = new DesignElement();
        }

        /// <summary>
        /// Gets or sets the type of the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("type", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public SiteType DataType
        {
            get
            {
                return this.type;
            }

            set
            {
                this.type = value;
            }
        }

        /// <summary>
        /// Gets or sets the name of the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("name", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                if (value.Length > 1)
                {
                    this.name = Miscallaneous.FixName(value);
                }
                else
                {
                    this.name = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the description of the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("description", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Description
        {
            get
            {
                return this.description;
            }

            set
            {
                this.description = value;
            }
        }

        /// <summary>
        /// Gets or sets the contact information of the site owner
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("contact", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Contact
        {
            get
            {
                return this.contact;
            }

            set
            {
                this.contact = value;
            }
        }

        /// <summary>
        /// Gets or sets the Domain account information of the site owner
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("owner", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Owner
        {
            get
            {
                return this.owner;
            }

            set
            {
                this.owner = value;
            }
        }

        /// <summary>
        /// Gets or sets the template that the site/area is based on
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("template", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Template
        {
            get
            {
                return this.template;
            }

            set
            {
                this.template = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the the site will be shown in the site directory
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("showinsitedirectory", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool ShowInSiteDirectory
        {
            get
            {
                return this.showInSiteDirectory;
            }

            set
            {
                this.showInSiteDirectory = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the permissions will be inherited or not
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("inheritPermissions", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public bool InheritPermissions
        {
            get
            {
                return this.inheritPermissions;
            }

            set
            {
                this.inheritPermissions = value;
            }
        }

        /// <summary>
        /// Gets or sets the security information that will be applied to the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("security", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public UserInfo UserInfo
        {
            get
            {
                return this.security;
            }

            set
            {
                this.security = value;
            }
        }

        /// <summary>
        /// Gets  a list of all the lists/libraries that will be created in the site/area
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("datacontainer", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public ListsCollection Lists
        {
            get
            {
                return this.lists;
            }
        }

        /// <summary>
        /// Gets a list of the subwebs/subareas that gets created in the site/area
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("container", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public SitesCollection SubSites
        {
            get
            {
                return this.subSites;
            }
        }

        /// <summary>
        /// Gets the design info (un-ghosted pages, web parts) of the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("design", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public DesignElement DesignElements
        {
            get
            {
                return this.design;
            }

            set
            {
                this.design = value;
            }
        }

        /// <summary>
        /// Gets or sets the template that is used when creating the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("webtemplate", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string WebTemplate
        {
            get
            {
                return this.webtemplate;
            }

            set
            {
                this.webtemplate = value;
            }
        }

        /// <summary>
        /// Gets or sets the configuration info for the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("configuration", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

        public string Configuration
        {
            get
            {
                return this.configuration;
            }

            set
            {
                this.configuration = value;
            }
        }

        /// <summary>
        /// Gets or sets the Url of the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("url", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Url
        {
            get
            {
                return this.url;
            }

            set
            {
                this.url = value;
            }
        }

        /// <summary>
        /// Gets or sets the locale of the site
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("lcid", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public int Locale
        {
            get
            {
                return this.lcid;
            }

            set
            {
                this.lcid = value;
            }
        }

        /// <summary>
        /// Gets or sets the site locale
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("sitelcid", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public int SiteLocale
        {
            get
            {
                return this.sitelcid;
            }

            set
            {
                this.sitelcid = value;
            }
        }

        /// <summary>
        /// Gets or sets the enum controls the site creation
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("operation", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public Verb Operation
        {
            get
            {
                return this.operation;
            }

            set
            {
                this.operation = value;
            }
        }

        /// <summary>
        /// Gets or sets the value that will contain all the extra properties not included in the xml schema
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("propertyBag", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

        public string PropertyBag
        {
            get
            {
                return this.propertyBag;
            }

            set
            {
                this.propertyBag = value;
            }
        }

        /// <summary>
        /// Gets or sets the timezone for the site
        /// </summary>
        public int TimezoneID
        {
            get
            {
                return this.timezoneID;
            }

            set
            {
                this.timezoneID = value;
            }
        }
    }

    /// <summary>
    /// Initializes a new instance of the UserInfo class
    /// </summary>
    /// <example>
    /// <code>
    /// //Add an contributor
    /// User user= new User();
    /// user.Account="DOMAIN\\User2";
    /// user.Role="contributor";
    /// user.Email="user2@domain.com";
    /// user.Name="Joe User";
    /// user.Type="Person";
    /// site.Security.User.Add(user);
    /// </code></example>
    public class UserInfo
    {
        /// <summary>
        /// This is the internal collection of users
        /// </summary>
        private UsersCollection users;

        /// <summary>
        /// This is the internal collection of roles
        /// </summary>
        private RolesCollection roles;
        
        /// <summary>
        /// Initializes a new instance of the UserInfo class
        /// </summary>
        /// <remarks>Instantiates the User member</remarks>
        public UserInfo()
        {
            this.users = new UsersCollection();
            this.roles = new RolesCollection();
        }
        
        /// <summary>
        /// Gets a list of all the users
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("user", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public UsersCollection Users
        {
            get
            {
                return this.users;
            }
        }

        /// <summary>
        /// Gets a list of all sitegroups that the Importer will create
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("role", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public RolesCollection Roles
        {
            get
            {
                return this.roles;
            }
        }
    }

    /// <summary>
    /// This is the class implementing the RootsCollection collection
    /// </summary>
    public class RootsCollection : ICollection
    {
         /// <summary>
         /// This is the internal collection
         /// </summary>
        private ArrayList rootContainers;

        /// <summary>
        /// Initializes a new instance of the RootsCollection class
        /// </summary>
        /// <remarks>Instantiates the rootContainers member</remarks>
        public RootsCollection()
        {
            this.rootContainers = new ArrayList();
        }
        
        #region ICollection Members

        /// <summary>
        /// Gets a value indicating whether access to the ArrayList is synchronized (thread-safe).
        /// </summary>
        /// <remarks>
        /// To guarantee the thread safety of the ArrayList, all operations must be done through the wrapper returned by the Synchronized method.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public bool IsSynchronized
        {
            get
            {
                return this.rootContainers.IsSynchronized;
            }
        }

        /// <summary>
        /// Gets a value indicating the number of objects in the collection. Read-only.
        /// </summary>
        public int Count
        {
            get
            {
                return this.rootContainers.Count;
            }
        }

        /// <summary>
        /// Gets an object that can be used to synchronize access to the ArrayList.
        /// </summary>
        /// <remarks>
        /// To create a synchronized version of the ArrayList, use the Synchronized method. However, derived classes can provide their own synchronized version of the ArrayList using the SyncRoot property. The synchronizing code must perform operations on the SyncRoot of the ArrayList, not directly on the ArrayList. This ensures proper operation of collections that are derived from other objects. 
        /// Specifically, it maintains proper synchronization with other threads that might be simultaneously modifying the ArrayList object.
        /// Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads could still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or 
        /// catch the exceptions resulting from changes made by other threads.
        /// </remarks>
        public object SyncRoot
        {
            get
            {
                return this.rootContainers.SyncRoot;
            }
        }

        /// <summary>
        /// Gets the element at the specified index.
        /// </summary>
        /// <param name="index">This is the index of the item</param>
        public Root this[int index]
        {
            get
            {
                return (Root)this.rootContainers[index];
            }
        }

        /// <summary>
        /// Copies the entire Root Array to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Root[] a, int index)
        {
            this.rootContainers.CopyTo(a, index);
        }

        /// <summary>
        /// Copies the entire ArrayList to a compatible one-dimensional Array, starting at the specified index of the target array.
        /// </summary>
        /// <param name="a">The one-dimensional Array that is the destination of the elements copied from ArrayList. The Array must have zero-based indexing. </param>
        /// <param name="index">The zero-based index in array at which copying begins</param>
        public void CopyTo(Array a, int index)
        {
            this.rootContainers.CopyTo(a, index);
        }

        #endregion

        #region IEnumerable Members

        /// <summary>
        /// Returns an enumerator that can iterate through the ArrayList.
        /// </summary>
        /// <returns>The enumerator</returns>
        public IEnumerator GetEnumerator()
        {
            return this.rootContainers.GetEnumerator();
        }

        #endregion
        /// <summary>
        /// Adds an object to the end of the ArrayList.
        /// </summary>
        /// <param name="newRootContainer">New RootContainer to be added to the list</param>
        public void Add(Root newRootContainer)
        {
            this.rootContainers.Add(newRootContainer);
        }
    }

    /// <summary>
    /// This is the encapsulation of the Root of the data
    /// </summary>
    /// <remarks><seealso cref="SharePoint.ImportExport.Core.Site"/><seealso cref="SharePoint.ImportExport.Core.Settings"/></remarks>
    public class Root
    {
        /// <summary>
        /// This is the name of the node
        /// </summary>
        private string name;

        /// <summary>
        /// This is the type of the node
        /// </summary>
        private SiteType type = SiteType.Undefined;

        /// <summary>
        /// This is the internal collection of sites
        /// </summary>
        private SitesCollection sites;

        /// <summary>
        /// Initializes a new instance of the Root class
        /// </summary>
        public Root()
        {
            this.sites = new SitesCollection();
        }

        /// <summary>
        /// Initializes a new instance of the Root class
        /// </summary>
        /// <param name="type">This is the SiteType</param>
        /// <param name="name">Name of Site/Area</param>
        public Root(SiteType type, string name)
        {
            this.DataType = type;
            this.Name = name;

            this.sites = new SitesCollection();
        }

        /// <summary>
        /// Gets or sets the type of the starting point of the import. 
        /// </summary>
        /// <remarks>Valid choices are SiteType.Site for WSS and SiteType.Area for SPS</remarks>
        [System.Xml.Serialization.XmlElementAttribute("type", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public SiteType DataType
        {
            get
            {
                return this.type;
            }

            set
            {
                this.type = value;
            }
        }

        /// <summary>
        /// Gets or sets the name of the root under which the sites will be imported
        /// </summary>
        /// <remarks>Usually Sites for WSS sites or Topics for Portal areas</remarks>
        [System.Xml.Serialization.XmlElementAttribute("name", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                this.name = value;
            }
        }

        /// <summary>
        /// Gets a list of all the sites that will be created
        /// </summary>
        [System.Xml.Serialization.XmlElementAttribute("container", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public SitesCollection Sites
        {
            get
            {
                return this.sites;
            }
        }
    }
}
